
#ifndef  RECOVERY_FS_FILE_FILEDESCRIPTOR_H
#define  RECOVERY_FS_FILE_FILEDESCRIPTOR_H


#include <cstdio>
namespace recovery {
namespace fs {
namespace file {

//TODO: think about the    default-generate-functions
//separate the Posix & Standard Impl
class FileDescriptor {
public:
    virtual ~FileDescriptor(){}

    virtual void * impl() const = 0;
    virtual void set(void * fd)  = 0;
    virtual bool isInvalid() const = 0;
    virtual void invalid()  = 0;
};

class PosixFileDescriptor : public FileDescriptor{
public:
    const static int INVALID_FD = -1;
    PosixFileDescriptor(int fd = INVALID_FD) : fd(fd) {
    }
    ~PosixFileDescriptor() override{
        fd = INVALID_FD;
    }

    void * impl() const override{
        return reinterpret_cast<void*>(fd);
    }
    void set(void * fd) override{
        if( reinterpret_cast<long>(fd) != this->fd){
            this->fd = reinterpret_cast<long>(fd);
        }
    }

    bool isInvalid() const override {
        return fd == INVALID_FD;
    }
    void invalid() override{
        set(reinterpret_cast<void*>(INVALID_FD));
    };
private:
    long fd;
};


class StandardFileDescriptor : public FileDescriptor{
public:
    static FILE * INVALID_FD;
    explicit StandardFileDescriptor(FILE * fd = INVALID_FD) : fd(fd) {
    }
    ~StandardFileDescriptor() override {
        fd = StandardFileDescriptor::INVALID_FD;
    }

    void* impl() const override {
        return static_cast<void *>(fd);
    }
    void set(void* fd)  override {
        if( static_cast<FILE*>(fd) != this->fd){
            this->fd = static_cast<FILE*>(fd);
        }
    }
    bool isInvalid() const override {
        return fd == StandardFileDescriptor::INVALID_FD;
    }
    void invalid() override {
        set(static_cast<void *>(StandardFileDescriptor::INVALID_FD));
    }
private:
    FILE * fd;
};

} //end of namespace file
} //end of namespace fs
} //end of namespace recovery


#endif   /* RECOVERY_FS_FILE_FILEDESCRIPTOR_H */
